package com.lmaos.allcontrol.beancontrol.utils_;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import com.lmaos.allcontrol.beancontrol.class_.ClassUtils;
import com.lmaos.allcontrol.beancontrol.class_.MyClassLibrary;
import com.lmaos.allcontrol.beancontrol.class_.MyClassLibrary.ClassLoaderNotFoundException;
import com.lmaos.allcontrol.beancontrol.entity_.LMClassParam;
import com.lmaos.allcontrol.beancontrol.field_.FieldUtils;
import com.lmaos.allcontrol.beancontrol.method_.MethodUtils;

/** 常用对象工具
 * 
 * @author lmaos 
 * 2016年11月16日 下午9:46:49
 */
public class ObjUtils {
	/** 
	 * 
	 * @param types
	 * @param params
	 * @return
	 */
	public static Object[] getParamsValue(Class[] types,Map<Class, Object> params){
		if(types == null){
			return null;
		}
		Object values[] = new Object[types.length];
		for (int i = 0; i < types.length; i++) {
			Class type = types[i];
			Object value = params.get(type);
			if(value!=null){
				values[i] = value;
			}else{
				values[i] = ClassUtils.getDefaultValue(type);
			}
		}
		return values;
	}
	
	/** 执行方法
	 * 
	 * @param obj
	 * @param method
	 * @param classParam
	 * @return
	 * @throws Exception
	 */
	public static Object executeMethod(Object obj,Method method,Map<Class,Object> classParam) throws Exception{
		Class[] types = method.getParameterTypes();
		Object[] values = getParamsValue(types, classParam);
		return MethodUtils.executeMethod(obj, method, values);
	}
	
	/** 执行方法
	 * 
	 * @param obj
	 * @param method
	 * @param classParam	可插入的参数
	 * @return
	 * @throws Exception
	 */
	public static Object executeMethod(Object obj,Method method,LMClassParam classParam) throws Exception{
		Class[] types = method.getParameterTypes();
		Object[] values = classParam.toObjects(method, types);
		return MethodUtils.executeMethod(obj, method, values);
	}
	
	public static Object getObject(Class cl,Class[] types,LMClassParam classParam) throws Exception{
		Constructor constructor = ClassUtils.indexConstructorByTypes(cl, types);
		if(constructor == null){
			return null;
		}
		Object[] values = classParam.toObjects(constructor, types);
		return ClassUtils.getObject(cl, types, values);
	}
	
	public static Object getObjectNoThrows(Class cl,Class[] types,LMClassParam classParam){
		try {
			return getObject(cl, types, classParam);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/** 设置对象的字段内容,值来自一个Map
	 * 
	 * @param obj
	 * @param insertValParams
	 */
	public static void setObjectFieldValue(Object obj,Map<String, Object> insertValParams){
		for (String fieldName : insertValParams.keySet()) {
			Object value = insertValParams.get(fieldName);
			if(value != null){
				FieldUtils.setFieldValue(obj, fieldName, value);
			}
		}
	}
	
	public static List getObjectsFieldValues(List objs,String name){
		List vals = new ArrayList();
		for (Object obj : objs) {
			Object val = FieldUtils.getFieldValue(obj, name);
			vals.add(val);
		}
		return vals;
	}
	/** 通过一个文本创建对象文本格式：object:加载器名称:类路径和名称(参数类型,参数类型)<br>
	 *   例如 getBaseValueObject("object:xxx.xx.B") 创建b对象，使用无参数构造
	 * @param text
	 * @return
	 */
	public static Object getBaseValueObject(String text){
		try {
			return getBaseValueObject(text, new LMClassParam());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			return null;
		} catch (ClassLoaderNotFoundException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/** 通过一个文本创建对象文本格式：object:加载器名称:类路径和名称(参数类型,参数类型)<br>
	 *  例如 getBaseValueObject("object:xxx.xx.B(int,int)") 创建b对象，使用两个参数int,int的构造
	 * @param text
	 * @param classParam 设置参数注入的方式
	 * @return
	 */
	public static Object getBaseValueObjectNoThrows(String text,LMClassParam classParam){
		try {
			return getBaseValueObject(text, classParam);
		} catch (ClassNotFoundException e) {
			System.err.println(e+";"+text);
			return null;
		} catch (ClassLoaderNotFoundException e) {
			e.printStackTrace();
			return null;
		}
	}
	/** 完整格式 object:loader:className(paramClass...) <br>
	 * 
	 *  简单格式 object:className(paramClass...) 或 object:className 这个是无参构造 <br>
	 *  
	 *  其他格式 int:10 或 double:100.0等<br>
	 *  不支持的基本类型：char
	 * @param text
	 * @param classParam
	 * @return
	 * @throws ClassNotFoundException
	 * @throws ClassLoaderNotFoundException
	 */
	public static Object getBaseValueObject(String text,LMClassParam classParam) throws ClassNotFoundException, ClassLoaderNotFoundException{
		if(text==null||text.trim().isEmpty()||text.equals("null")){
			return null;
		}
		int splitIndex = text.indexOf(":");
		if(splitIndex == -1){
			return null;
		}
		String type = text.substring(0,splitIndex).toLowerCase();
		String value = text.substring(splitIndex+1);
		if(type.equals("int")||type.equals("number")){
			return NumberUtils.toInt(value, 0);
		}else if(type.equals("short")){
			return NumberUtils.toShort(value, (short) 0);
		}else if(type.equals("byte")){
			return NumberUtils.toByte(value, (byte) 0);
		}else if(type.equals("long")){
			return NumberUtils.toLong(value, 0L);
		}else if(type.equals("float")){
			return NumberUtils.toFloat(value, 0.0F);
		}else if(type.equals("double")){
			return NumberUtils.toDouble(value, 0.0D);
		}else if(type.equals("boolean")){
			return NumberUtils.toBoolean(value);
		}else if(type.equals("string")){
			return value;
		}else if(value.equals("null")){
			return null;
		}else if(type.equals("object")){
			
			if(classParam!=null){
				String name = "";
				int nameIndexEnd = value.indexOf(":");
				if(nameIndexEnd!=-1){
					name = value.substring(0,nameIndexEnd);
					value = value.substring(nameIndexEnd+1);
				}
				String className = getString(value, "", "(");
				Class types[] = getTypesByString(value, "(", ")", ",", classParam.getClassLoader(name));
				Class cl = classParam.loadClass(name,className);
				return getObjectNoThrows(cl, types, classParam);
			}
			return ClassUtils.getObject(value);
		}else {
			return value;
		}
	}
	
	public static String getString(String text,String start,String end){
		if(start == null){
			start = "";
		}
		if(end == null){
			end = "";
		}
		int startIndex = text.indexOf(start);
		int endIndex = text.lastIndexOf(end);
		if(startIndex == -1){
			return null;
		}
		if(endIndex == -1){
			endIndex = text.length();
		}
		String result = null;
		if(start.isEmpty()){
			result = text.substring(startIndex,endIndex);
		}else{
			result = text.substring(startIndex+1,endIndex);
		}
		return result;
	}
	/** 获取这一组类型
	 * 
	 * @param text 类型文本 
	 * @param start 开始字符
	 * @param end	结束字符
	 * @param split	每个类型分隔符
	 * @param classLoader
	 * @return
	 * @throws ClassNotFoundException
	 */
	public static Class[] getTypesByString(String text,String start,String end,String split,ClassLoader classLoader) throws ClassNotFoundException{
		
		if(classLoader == null){
			classLoader = ObjUtils.class.getClassLoader();
		}
		String classAll = getString(text, start, end);
		if(classAll == null||classAll.trim().isEmpty()){
			return null;
		}
		String class_s[] = classAll.split(",");
		Class cls[] = new Class[class_s.length];
		for (int i = 0; i < cls.length; i++) {
			cls[i] = ClassUtils.getBasheType(class_s[i], classLoader);
			if(cls[i]==null){
				throw new ClassNotFoundException(class_s[i]);
			}
		}
		return cls;
	}
	
	public static Set<Object> getBaseValueObjectToSet(String[] texts,LMClassParam classParam){
		Set<Object> set = new HashSet<Object>();
		if(texts == null){
			return set;
		}
		for (String text : texts) {
			try {
				set.add(getBaseValueObject(text, classParam));
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			} catch (ClassLoaderNotFoundException e) {
				e.printStackTrace();
			}
		}
		return set;	
	}
	
	/** 获取 class 来自文本 例如：loader:className   加载器名称:类路径和名称
	 * 
	 * @param text
	 * @return
	 * @throws ClassNotFoundException 类不存在
	 * @throws ClassLoaderNotFoundException 类加载器不存在
	 */
	public static Class getBaseClassByText(String text) throws ClassNotFoundException, ClassLoaderNotFoundException{
		MyClassLibrary classLibrary = MyClassLibrary.getClassLibrary();
		String name = "";
		int nameIndexEnd = text.indexOf(":");
		if(nameIndexEnd!=-1){
			name = text.substring(0,nameIndexEnd);
			text = text.substring(nameIndexEnd+1);
		}
		
		return classLibrary.loadClass(name, text);
	}
	
	public static void setObjectBaseProperty(Object obj,Map<String,Object> property){
		for (String fieldName : property.keySet()) {
			Object value = property.get(fieldName);
			if(value!=null){
				FieldUtils.setFieldValue(obj, fieldName, value);
			}
		}
	} 
	

	/** 休眠
	 * 
	 * @param time
	 * @param in
	 * @return
	 */
	public static boolean sleep(long time,boolean in){
		return in&&sleep(time);
	}
	/** 休眠
	 * 
	 * @param time 休眠时间
	 * @return
	 */
	public static boolean sleep(long time){
		try {
			Thread.sleep(time);
			return true;
		} catch (InterruptedException e) {
			return false;
		}
	}
}
